home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / tex_cube / texture.c++ < prev    next >
C/C++ Source or Header  |  1996-11-11  |  21KB  |  814 lines

  1. /*
  2.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  * Permission to use, copy, modify, and distribute this software for
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  * US Government Users Restricted Rights
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  36.  */
  37. #include "texture.h"
  38.  
  39. extern "C" {
  40. #include "myimage.h"
  41. };
  42.  
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <limits.h>
  46. #include <malloc.h>
  47.  
  48. #define Malloc(ptr, type, count) \
  49. { \
  50.   ptr = (type *)malloc(count * sizeof(type)); \
  51.   if (ptr == NULL && count != 0 && sizeof(type) != 0) { \
  52.     fprintf(stderr, "malloc failed.\n"); \
  53.     fprintf(stderr, "%d bytes requested.\n", count * sizeof(type)); \
  54.     exit(1); \
  55.   } \
  56. }
  57.  
  58. inline int sizeof_format(GLenum format) 
  59. {
  60.   switch(format) {
  61.   case GL_COLOR_INDEX:
  62.   case GL_RED:
  63.   case GL_GREEN:
  64.   case GL_BLUE:
  65.   case GL_ALPHA:
  66.   case GL_LUMINANCE:
  67.     return 1;
  68.   case GL_LUMINANCE_ALPHA:
  69.     return 2;
  70.   case GL_RGB:
  71.     return 3;
  72.   case GL_RGBA:
  73.     return 4;
  74.   default:
  75.     fprintf(stderr, "Unrecognized pixel format %d.\n", format);
  76.     return 0;
  77.   }
  78. }
  79.  
  80. inline int sizeof_type(GLenum type)
  81. {
  82.   switch(type) {
  83.   case GL_UNSIGNED_BYTE:
  84.     return sizeof(GLubyte);
  85.   case GL_BYTE:
  86.     return sizeof(GLbyte);
  87.   case GL_UNSIGNED_SHORT:
  88.     return sizeof(GLushort);
  89.   case GL_SHORT:
  90.     return sizeof(GLshort);
  91.   case GL_UNSIGNED_INT:
  92.     return sizeof(GLuint);
  93.   case GL_INT:
  94.     return sizeof(GLint);
  95.   default:
  96.     fprintf(stderr, "Unrecognized pixel type %d.\n", type);
  97.     return 0;
  98.   }
  99. }
  100.  
  101. inline float max_value(GLenum type)
  102. {
  103.   switch(type) {
  104.   case GL_UNSIGNED_BYTE:
  105.     return 255.0;
  106.   case GL_BYTE:
  107.     return 127.0;
  108.   case GL_UNSIGNED_SHORT:
  109.     return 65535.0;
  110.   case GL_SHORT:
  111.     return 32767.0;
  112.   case GL_UNSIGNED_INT:
  113.     return 4294967295.0;
  114.   case GL_INT:
  115.     return 2147483647.0;
  116.   default:
  117.     fprintf(stderr, "Unrecognized pixel type %d.\n", type);
  118.     return 0;
  119.   }
  120. }
  121.  
  122. inline float max_value_inv(GLenum type)
  123. {
  124.   switch(type) {
  125.   case GL_UNSIGNED_BYTE:
  126.     return 3.9215686e-3;
  127.   case GL_BYTE:
  128.     return 7.8740157e-3;
  129.   case GL_UNSIGNED_SHORT:
  130.     return 1.5259022e-5;
  131.   case GL_SHORT:
  132.     return 3.0518509e-5;
  133.   case GL_UNSIGNED_INT:
  134.     return 2.3283064e-10;
  135.   case GL_INT:
  136.     return 4.46566129e-10;
  137.   default:
  138.     fprintf(stderr, "Unrecognized pixel type %d.\n", type);
  139.     return 0;
  140.   }
  141. }
  142.  
  143. inline float luminance(float r, float g, float b) 
  144. {
  145.   return(.299*r + .587*g + .114*b);
  146. }
  147.  
  148. texture::texture() 
  149. {
  150. }
  151.  
  152. void texture::open()
  153. {
  154.   pixels = NULL;
  155.   pixels_size = 0;
  156.   display_format = DEFAULT_DISPLAY_FORMAT;
  157.   display_type = DEFAULT_DISPLAY_TYPE;
  158.   alignment = DEFAULT_ALIGNMENT;
  159.   components = DEFAULT_COMPONENTS;
  160.   level = DEFAULT_LEVEL;
  161.   
  162.   min_filter = DEFAULT_MIN_FILTER;
  163.   max_filter = DEFAULT_MAX_FILTER;
  164.  
  165.   environment = DEFAULT_ENVIRONMENT;
  166.  
  167. }
  168.  
  169. void texture::set_display_format(GLenum new_display_format)
  170. {
  171.   reformat(new_display_format, display_type, alignment);
  172. }
  173.  
  174. GLenum texture::get_display_format()
  175. {
  176.   return display_format;
  177. }
  178.  
  179. void texture::set_display_type(GLenum new_display_type)
  180. {
  181.   reformat(display_format, new_display_type, alignment);
  182. }
  183.  
  184. GLenum texture::get_display_type()
  185. {
  186.   return display_type;
  187. }
  188.  
  189. void texture::set_alignment(int new_alignment)
  190. {
  191.   reformat(display_format, display_type, new_alignment);
  192. }
  193.  
  194. int texture::get_alignment()
  195. {
  196.   return alignment;
  197. }
  198.  
  199. void texture::set_components(int new_components)
  200. {
  201.   components = new_components;
  202. }
  203.  
  204. int texture::get_components()
  205. {
  206.   return components;
  207. }
  208.  
  209. void texture::set_level(int new_level)
  210. {
  211.   level = new_level;
  212. }
  213.  
  214. int texture::get_level()
  215. {
  216.   return level;
  217. }
  218.  
  219. void texture::set_min_filter(GLenum new_min_filter) 
  220. {
  221.   min_filter = new_min_filter;
  222. }
  223.  
  224. GLenum texture::get_min_filter() 
  225. {
  226.   return min_filter;
  227. }
  228.  
  229. void texture::set_max_filter(GLenum new_max_filter)
  230. {
  231.   max_filter = new_max_filter;
  232. }
  233.  
  234. GLenum texture::get_max_filter()
  235. {
  236.   return max_filter;
  237. }
  238.  
  239. int texture::get_width()
  240. {
  241.   return width;
  242. }
  243.  
  244. int texture::get_height()
  245. {
  246.   return height;
  247. }
  248.  
  249. void texture::set_environment(GLenum new_environment)
  250. {
  251.   environment = new_environment;
  252. }
  253.  
  254. GLenum texture::get_environment()
  255. {
  256.   return environment;
  257. }
  258.  
  259. void texture::create_color(int total_size,
  260.                float r, float g, float b, float a, float l)
  261. {
  262.   int x, y;
  263.   width = height = total_size;
  264.   pixels_alloc(width * height);
  265.   for (y = 0; y < height; y++)
  266.     for (x = 0; x < width; x++)
  267.       assign_pixel(x, y, r, g, b, a, l);
  268. }
  269.  
  270. void texture::create_checkerboard(int total_size, int block_size,
  271.                   float r1, float g1, float b1,
  272.                   float alpha1, float lum1,
  273.                   float r2, float g2, float b2,
  274.                   float alpha2, float lum2) 
  275. {
  276.   int x, y;
  277.   width = height = total_size;
  278.   pixels_alloc(width * height);
  279.   for (y = 0; y < height; y++)
  280.     for (x = 0; x < width; x++)
  281.       if ((((x /block_size) % 2) + ((y / block_size) % 2)) % 2)
  282.     assign_pixel(x, y, r1, g1, b1, alpha1, lum1);
  283.       else assign_pixel(x, y, r2, g2, b2, alpha2, lum2);
  284. }
  285.  
  286. void texture::create_diag_stripes(int total_size, int stripe_width,
  287.                   float r1, float g1, float b1,
  288.                   float alpha1, float lum1,
  289.                   float r2, float g2, float b2,
  290.                   float alpha2, float lum2) 
  291.  
  292. {
  293.   int x, y;
  294.   width = height = total_size;
  295.   pixels_alloc(width * height);
  296.   for (y = 0; y < height; y++)
  297.     for (x = 0; x < width; x++)
  298.       if (((x + y) / stripe_width) % 2) 
  299.     assign_pixel(x, y, r1, g1, b1, alpha1, lum1);
  300.       else assign_pixel(x, y, r2, g2, b2, alpha2, lum2);
  301. }
  302.  
  303. void texture::create_from_file(char *fname) 
  304. {
  305.   IMAGE *image;
  306.   unsigned short *rbuf, *gbuf, *bbuf;
  307.   float r, g, b;
  308.   int x, y;
  309.  
  310.   image = iopen(fname, "r");
  311.   if (image == NULL) {
  312.     fprintf(stderr, "Unable to open file %s.\n", fname);
  313.     exit(1);
  314.   }
  315.  
  316.   width = image->xsize;
  317.   height = image->ysize;
  318.  
  319.   Malloc(rbuf, unsigned short, image->xsize);
  320.   Malloc(gbuf, unsigned short, image->xsize);
  321.   Malloc(bbuf, unsigned short, image->xsize);
  322.  
  323.   pixels_alloc(width * height);
  324.  
  325.   for (y = 0; y < image->ysize; y++) {
  326.     getrow(image, rbuf, y, 0);
  327.     getrow(image, gbuf, y, 1);
  328.     getrow(image, bbuf, y, 2);
  329.     for (x = 0; x < image->xsize; x++) {
  330.       r = (float)rbuf[x] / 255.0;
  331.       g = (float)gbuf[x] / 255.0;
  332.       b = (float)bbuf[x] / 255.0;
  333.       assign_pixel(x, y, r, g, b, 1.0, luminance(r, g, b));
  334.     }
  335.   }
  336.  
  337.   if (image->xsize) {
  338.     free(rbuf);
  339.     free(gbuf);
  340.     free(bbuf);
  341.   }
  342.  
  343.   /* There must be some way to close an image file, but I don't know
  344.    * know what it is, so we'll just leave it open for now. */
  345.  
  346. }
  347.  
  348. void texture::map_lum_to_alpha() 
  349. {
  350.   int x, y;
  351.   float lum;
  352.  
  353.   if (pixels_size == 0) {
  354.     fprintf(stderr, "Cannot map luminance to alpha:  no image in memory.\n");
  355.     return;
  356.   }
  357.   for (y = 0; y < height; y++)
  358.     for (x = 0; x < width; x++) 
  359.       assign_pixel_a(x, y, pixel_lum(x, y));
  360. }
  361.  
  362. void texture::draw_pixels()
  363. {
  364.   draw_pixels(0, 0, width, height);
  365. }
  366.  
  367. void texture::draw_pixels(int x1, int y1, int x2, int y2)
  368. {
  369.   glPixelStorei(GL_PACK_ROW_LENGTH, width);
  370.   glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1);
  371.   glPixelStorei(GL_UNPACK_SKIP_ROWS, y1); 
  372.   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
  373.   glDrawPixels(x2-x1, y2-y1, display_format, display_type, pixels);
  374. }
  375.  
  376. void texture::setup_texture() 
  377. {
  378.   setup_texture(0, 0, width, height);
  379. }
  380.  
  381. void texture::setup_texture(int x1, int y1, int x2, int y2)
  382. {
  383.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
  384.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter);
  385.  
  386.   if ((components < 3 && environment == GL_DECAL) || 
  387.       (components > 2 && environment == GL_BLEND)) 
  388.     fprintf(stderr, 
  389.         "Warning:  illegal component / environment combination.\n");
  390.   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, environment);
  391.  
  392.   glPixelStorei(GL_PACK_ROW_LENGTH, width);
  393.   glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1);
  394.   glPixelStorei(GL_UNPACK_SKIP_ROWS, y1);
  395.   glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); 
  396. }
  397.  
  398. void texture::specify_texture()
  399. {
  400.   specify_texture(0, 0, width, height);
  401. }
  402.  
  403.  
  404. void texture::specify_texture(int x1, int y1, int x2, int y2)
  405. {
  406.   setup_texture(x1, y1, x2, y2);
  407.  
  408.   /* Create the mip map if required, otherwise don't */
  409.   if (min_filter == GL_NEAREST || min_filter == GL_LINEAR) 
  410.     glTexImage2D(GL_TEXTURE_2D, level, components,
  411.          x2-x1, y2-y1, 0, display_format, display_type,
  412.          pixels);
  413.   else gluBuild2DMipmaps(GL_TEXTURE_2D, components, x2-x1,
  414.              y2-y1, display_format, display_type,
  415.              pixels);
  416. }
  417.  
  418. void texture::specify_mipmap() 
  419. {
  420.   specify_mipmap(0, 0, width, height);
  421. }
  422.  
  423. void texture::specify_mipmap(int x1, int y1, int x2, int y2)
  424. {
  425.   glTexImage2D(GL_TEXTURE_2D, level, components, 
  426.            x2-x1, y2-y1, 0, display_format, display_type,
  427.            pixels);
  428. }
  429.  
  430. void texture::pixels_alloc() 
  431. {
  432.   pixels_alloc(height * width);
  433. }
  434.  
  435. void texture::pixels_alloc(int size)
  436. {
  437.   int size_bytes;
  438.  
  439.   size_bytes = 
  440.     size * sizeof_format(display_format) * sizeof_type(display_type);
  441.   if (pixels_size == 0) {
  442.     pixels = malloc(size_bytes);
  443.     pixels_size = size_bytes;
  444.   }
  445.   else if (size_bytes > pixels_size) {
  446.     pixels = realloc(pixels, size_bytes);
  447.     pixels_size = size_bytes;
  448.   }
  449.   if (pixels == NULL && size_bytes != 0) {
  450.     fprintf(stderr, "Malloc failed - unable to allocate %d bytes.\n",
  451.         size_bytes);
  452.     exit(1);
  453.   }
  454.   
  455. }
  456.  
  457. void texture::pixels_free()
  458. {
  459.   if (pixels != NULL) free(pixels);
  460.   pixels = NULL;
  461.   pixels_size = 0;
  462. }
  463.  
  464. #define ASSIGN_PIXEL2(element, value, el_length, enum, type) \
  465.  case enum: \
  466.   ((type *)((char *)pixels + y*rowlength))[x*el_length + element] = \
  467.   (type)(value * max_value(enum)); \
  468. break; 
  469.  
  470. #define ASSIGN_PIXEL(element, value, el_length) \
  471. switch(display_type) { \
  472.   ASSIGN_PIXEL2(element, value, el_length, GL_UNSIGNED_BYTE, GLubyte); \
  473.   ASSIGN_PIXEL2(element, value, el_length, GL_BYTE, GLbyte); \
  474.   ASSIGN_PIXEL2(element, value, el_length, GL_UNSIGNED_SHORT, GLushort); \
  475.   ASSIGN_PIXEL2(element, value, el_length, GL_SHORT, GLshort); \
  476.   ASSIGN_PIXEL2(element, value, el_length, GL_UNSIGNED_INT, GLuint); \
  477.   ASSIGN_PIXEL2(element, value, el_length, GL_INT, GLint); \
  478. }
  479.  
  480. void texture::assign_pixel(int x, int y, float r, float g, float b, float a,
  481.                float l)
  482. {
  483.   assign_pixel(x, y, r, g, b, a, l, display_format, display_type, alignment);
  484. }
  485.  
  486. void texture::assign_pixel(int x, int y, float r, float g, float b, float a,
  487.                float l, GLenum display_format, 
  488.                GLenum display_type, int alignment)
  489. {
  490.   int rowlength;
  491.  
  492.   rowlength = row_length();
  493.   switch (display_format) {
  494.   case GL_RED:
  495.     ASSIGN_PIXEL(0, r, 1);
  496.     break;
  497.   case GL_GREEN:
  498.     ASSIGN_PIXEL(0, g, 1);
  499.     break;
  500.   case GL_BLUE:
  501.     ASSIGN_PIXEL(0, b, 1);
  502.     break;
  503.   case GL_ALPHA:
  504.     ASSIGN_PIXEL(0, a, 1);
  505.     break;
  506.   case GL_LUMINANCE:
  507.     ASSIGN_PIXEL(0, l, 1);
  508.     break;
  509.   case GL_LUMINANCE_ALPHA:
  510.     ASSIGN_PIXEL(0, l, 2);
  511.     ASSIGN_PIXEL(1, a, 2);
  512.     break;
  513.   case GL_RGB:
  514.     ASSIGN_PIXEL(0, r, 3);
  515.     ASSIGN_PIXEL(1, g, 3);
  516.     ASSIGN_PIXEL(2, b, 3);
  517.     break;
  518.   case GL_RGBA:
  519.     ASSIGN_PIXEL(0, r, 4);
  520.     ASSIGN_PIXEL(1, g, 4);
  521.     ASSIGN_PIXEL(2, b, 4);
  522.     ASSIGN_PIXEL(3, a, 4);
  523.     break;
  524.   default:
  525.     fprintf(stderr, "Unrecognized display format %d\n", display_format);
  526.     exit(1);
  527.   }
  528. }
  529.  
  530. inline void texture::assign_pixel_a(int x, int y, float a)
  531. {
  532.   int rowlength = row_length();
  533.   if (display_format == GL_LUMINANCE_ALPHA) {
  534.     ASSIGN_PIXEL(1, a, 2); 
  535.   } else if (display_format == GL_RGBA) ASSIGN_PIXEL(3, a, 4);
  536.   return;
  537. }
  538.  
  539. void texture::reformat(GLenum new_display_format, GLenum new_display_type,
  540.                int new_alignment)
  541. {
  542.   GLenum old_display_format = display_format;
  543.   GLenum old_display_type = display_type;
  544.   int old_alignment = alignment;
  545.   int old_pixels_size = pixels_size;
  546.   int direction;
  547.   int old_rowlength, new_rowlength;
  548.   int x, y;
  549.   
  550.   /* Make sure that something acutally has changed. */
  551.   if (new_display_format == old_display_format &&
  552.       new_display_type == old_display_type && 
  553.       new_alignment == old_alignment) return;
  554.  
  555.   if (old_pixels_size == 0) {
  556.     display_format = new_display_format;
  557.     display_type = new_display_type;
  558.     alignment = new_alignment;
  559.     return;
  560.   }
  561.  
  562.   old_rowlength = row_length(old_display_format, old_display_type,
  563.                  old_alignment);
  564.   new_rowlength = row_length(new_display_format, new_display_type,
  565.                  new_alignment);
  566.   
  567.   /* Seems like this should cause a core dump since the amount of 
  568.    * space has not changed yet... */
  569.   pixels_alloc();
  570.  
  571.   if (new_rowlength > old_rowlength) direction = -1;
  572.   else direction = 1;
  573.  
  574.   for (y = (direction == 1 ? 0 : height - 1);
  575.        y < height && y >= 0; y += direction) 
  576.     for (x = (direction == 1 ? 0 : width - 1);
  577.          x < height && x >= 0; x += direction) 
  578.       {
  579.     assign_pixel(x, y, pixel_r(x, y), pixel_g(x, y), pixel_b(x, y),
  580.              pixel_alpha(x, y), pixel_lum(x, y), new_display_format,
  581.              new_display_type, new_alignment);
  582.       }
  583.  
  584.   display_format = new_display_format;
  585.   display_type = new_display_type;
  586.   alignment = new_alignment;
  587.  
  588. }
  589.  
  590. int texture::row_length()
  591. {
  592.   return row_length(display_format, display_type, alignment);
  593. }
  594.  
  595. int texture::row_length(GLenum display_format, GLenum display_type,
  596.             int alignment)
  597. {
  598.   int row_length;
  599.   row_length = width * sizeof_format(display_format) * 
  600.     sizeof_type(display_type);
  601.   row_length += row_length % alignment;
  602.   return row_length;
  603. }
  604.  
  605. #define PIXEL_VALUE2(enum, type, index) \
  606. ((float) \
  607. ((type *)((char *)pixels + y*rowlength)) \
  608. [x*sizeof_format(display_format) + index] * max_value_inv(enum))
  609.  
  610. #define PIXEL_VALUE(enum, type, index) \
  611.  case enum: \
  612.   return PIXEL_VALUE2(enum, type, index);
  613.  
  614. #define PIXEL_AVG_VALUE(enum, type) \
  615.  case enum: \
  616.   return (luminance(PIXEL_VALUE2(enum, type, 0), \
  617.             PIXEL_VALUE2(enum, type, 1), \
  618.             PIXEL_VALUE2(enum, type, 2)));
  619.  
  620. inline float texture::pixel_r(int x, int y)
  621. {
  622.   return pixel_r(x, y, display_format, display_type, alignment);
  623. }
  624.  
  625. inline float texture::pixel_r(int x, int y, GLenum display_format, 
  626.   GLenum display_type, int alignment)
  627. {
  628.   int rowlength;
  629.   
  630.   rowlength = row_length(display_format, display_type, alignment);
  631.  
  632.   switch(display_format) {
  633.   case GL_RED:
  634.   case GL_RGB:
  635.   case GL_RGBA:
  636.   case GL_LUMINANCE:
  637.   case GL_LUMINANCE_ALPHA:
  638.     switch(display_type) {
  639.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 0);
  640.       PIXEL_VALUE(GL_BYTE, GLbyte, 0);
  641.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 0);
  642.       PIXEL_VALUE(GL_SHORT, GLshort, 0);
  643.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 0);
  644.       PIXEL_VALUE(GL_INT, GLint, 0);
  645.     }
  646.     break;
  647.   case GL_GREEN:
  648.   case GL_BLUE:
  649.     return 0.0;
  650.   }
  651. }
  652.  
  653. inline float texture::pixel_g(int x, int y)
  654. {
  655.   return pixel_g(x, y, display_format, display_type, alignment);
  656. }
  657.  
  658. inline float texture::pixel_g(int x, int y, GLenum display_format, 
  659.                    GLenum display_type, int alignment)
  660. {
  661.   int rowlength;
  662.   
  663.   rowlength = row_length(display_format, display_type, alignment);
  664.  
  665.   switch(display_format) {
  666.   case GL_GREEN:
  667.   case GL_LUMINANCE:
  668.   case GL_LUMINANCE_ALPHA:
  669.     switch(display_type) {
  670.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 0);
  671.       PIXEL_VALUE(GL_BYTE, GLbyte, 0);
  672.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 0);
  673.       PIXEL_VALUE(GL_SHORT, GLshort, 0);
  674.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 0);
  675.       PIXEL_VALUE(GL_INT, GLint, 0);
  676.     }
  677.     break;
  678.   case GL_RGB:
  679.   case GL_RGBA:
  680.     switch(display_type) {
  681.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 1);
  682.       PIXEL_VALUE(GL_BYTE, GLbyte, 1);
  683.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 1);
  684.       PIXEL_VALUE(GL_SHORT, GLshort, 1);
  685.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 1);
  686.       PIXEL_VALUE(GL_INT, GLint, 1);
  687.     }
  688.     break;
  689.   case GL_RED:
  690.   case GL_BLUE:
  691.     return 0.0;
  692.   }
  693. }
  694.  
  695. inline float texture::pixel_b(int x, int y)
  696. {
  697.   return pixel_b(x, y, display_format, display_type, alignment);
  698. }
  699.  
  700. inline float texture::pixel_b(int x, int y, GLenum display_format, 
  701.                    GLenum display_type, int alignment)
  702. {
  703.   int rowlength;
  704.   
  705.   rowlength = row_length(display_format, display_type, alignment);
  706.  
  707.   switch(display_format) {
  708.   case GL_BLUE:
  709.   case GL_LUMINANCE:
  710.   case GL_LUMINANCE_ALPHA:
  711.     switch(display_type) {
  712.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 0);
  713.       PIXEL_VALUE(GL_BYTE, GLbyte, 0);
  714.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 0);
  715.       PIXEL_VALUE(GL_SHORT, GLshort, 0);
  716.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 0);
  717.       PIXEL_VALUE(GL_INT, GLint, 0);
  718.     }
  719.     break;
  720.   case GL_RGB:
  721.   case GL_RGBA:
  722.     switch(display_type) {
  723.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 2);
  724.       PIXEL_VALUE(GL_BYTE, GLbyte, 2);
  725.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 2);
  726.       PIXEL_VALUE(GL_SHORT, GLshort, 2);
  727.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 2);
  728.       PIXEL_VALUE(GL_INT, GLint, 2);
  729.     }
  730.     break;
  731.   case GL_RED:
  732.   case GL_GREEN:
  733.     return 0.0;
  734.   }
  735. }
  736.  
  737. inline float texture::pixel_alpha(int x, int y)
  738. {
  739.   return pixel_alpha(x, y, display_format, display_type, alignment);
  740. }
  741.  
  742. inline float texture::pixel_alpha(int x, int y, GLenum display_format, 
  743.                    GLenum display_type, int alignment)
  744. {
  745.   int rowlength;
  746.  
  747.   rowlength = row_length(display_format, display_type, alignment);
  748.   switch(display_format) {
  749.   case GL_RGBA:
  750.     switch(display_type) {
  751.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 3);
  752.       PIXEL_VALUE(GL_BYTE, GLbyte, 3);
  753.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 3);
  754.       PIXEL_VALUE(GL_SHORT, GLshort, 3);
  755.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 3);
  756.       PIXEL_VALUE(GL_INT, GLint, 3);
  757.     }
  758.   case GL_LUMINANCE_ALPHA:
  759.     switch(display_type) {
  760.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 1);
  761.       PIXEL_VALUE(GL_BYTE, GLbyte, 1);
  762.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 1);
  763.       PIXEL_VALUE(GL_SHORT, GLshort, 1);
  764.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 1);
  765.       PIXEL_VALUE(GL_INT, GLint, 1);
  766.     }
  767.   default:
  768.     return 1.0;
  769.   }
  770. }
  771.  
  772. inline float texture::pixel_lum(int x, int y)
  773. {
  774.   return pixel_lum(x, y, display_format, display_type, alignment);
  775. }
  776.  
  777. inline float texture::pixel_lum(int x, int y, GLenum display_format, 
  778.                 GLenum display_type, int alignment)
  779. {
  780.   int rowlength;
  781.  
  782.   rowlength = row_length(display_format, display_type, alignment);
  783.  
  784.   switch(display_format) {
  785.   case GL_RED:
  786.   case GL_GREEN:
  787.   case GL_BLUE:
  788.   case GL_LUMINANCE:
  789.   case GL_LUMINANCE_ALPHA:
  790.     switch(display_type) {
  791.       PIXEL_VALUE(GL_UNSIGNED_BYTE, GLubyte, 0);
  792.       PIXEL_VALUE(GL_BYTE, GLbyte, 0);
  793.       PIXEL_VALUE(GL_UNSIGNED_SHORT, GLushort, 0);
  794.       PIXEL_VALUE(GL_SHORT, GLshort, 0);
  795.       PIXEL_VALUE(GL_UNSIGNED_INT, GLuint, 0);
  796.       PIXEL_VALUE(GL_INT, GLint, 0);
  797.     }
  798.     break;
  799.   case GL_RGB:
  800.   case GL_RGBA:
  801.     switch(display_type) {
  802.       PIXEL_AVG_VALUE(GL_UNSIGNED_BYTE, GLubyte);
  803.       PIXEL_AVG_VALUE(GL_BYTE, GLbyte);
  804.       PIXEL_AVG_VALUE(GL_UNSIGNED_SHORT, GLushort);
  805.       PIXEL_AVG_VALUE(GL_SHORT, GLshort);
  806.       PIXEL_AVG_VALUE(GL_UNSIGNED_INT, GLuint);
  807.       PIXEL_AVG_VALUE(GL_INT, GLint);
  808.     }
  809.   default:
  810.     fprintf(stderr, "Unrecognized display format %d\n", display_format);
  811.     return 0.0;
  812.   }
  813. }
  814.